package com.gqyin.demo.dao.impl;

import com.gqyin.demo.dao.UserRepository;
import com.gqyin.demo.domain.User;
import com.gqyin.demo.domain.UserQueryParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author guiqing.yin
 * 2024-04-07 16:48
 */
@Repository
public class UserRepositoryImpl extends BaseRepositoryImpl<User, String> implements UserRepository {

    @Autowired
    public UserRepositoryImpl(MongoTemplate mongoTemplate) {
        super(mongoTemplate);
    }

    @Override
    public User findByName(String name) {
        Query query = new Query();
        query.addCriteria(Criteria.where("name").is(name));
        return mongoTemplate.findOne(query, User.class);
    }

    @Override
    public Page<User> query(UserQueryParam queryParam) {
        Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(queryParam.getName())) {
            criteria.and("name").regex(Pattern.compile(queryParam.getName(), Pattern.CASE_INSENSITIVE));
        }
        if (StringUtils.isNotBlank(queryParam.getPhoneNumber())) {
            criteria.and("phoneNumber").regex(Pattern.compile(queryParam.getPhoneNumber(), Pattern.CASE_INSENSITIVE));
        }
        if (StringUtils.isNotBlank(queryParam.getEmail())) {
            criteria.and("email").regex(Pattern.compile(queryParam.getEmail(), Pattern.CASE_INSENSITIVE));
        }

        Query query = new Query(criteria);

        List<Sort.Order> sortOrders = new ArrayList<>();
        if (!CollectionUtils.isEmpty(queryParam.getOrders())) {
            queryParam.getOrders().forEach((property, direction) -> sortOrders.add(new Sort.Order(direction, property)));
        }
        PageRequest pageRequest = PageRequest.of(queryParam.getPage(), queryParam.getSize(), Sort.by(sortOrders));

        List<User> result = mongoTemplate.find(query.with(pageRequest), User.class);
        long total = mongoTemplate.count(query, User.class);

        return new PageImpl<>(result, pageRequest, total);
    }
}
